﻿\subsection{测试：在用户进程中发起系统调用}

采用相同的方法，可以将本节中实现的创建进程函数封装为可供用户使用的 \lstinline{CreateProcess} 系统调用。

操作系统内核封装第一条内核线程后，将从磁盘中读取下述测试程序，调用 \lstinline{InitializeMainThread} 创建第一个进程 \lstinline{System}。

以下为测试使用的 \lstinline{System.exe} 程序源代码。

\begin{minted}[breaklines, breakautoindent=true]{cpp}
#include <Utility/CLib.h>
#include <Utility/intrinsic.h>
#include <Kernel/syscall.h>
int main(int argc, char* argv[], char* envp[])
{
    printf("Main thread of system process established.\r\n");
    WORD wCS;
    WORD wDS;
    WORD wSS;
    __asm {
        mov wCS, cs
        mov wDS, ds
        mov wSS, ss
    }
    printf("CS = 0x%x, DS = 0x%x, SS = 0x%x, EFLAGS = 0x%x, CR3 = 0x%x.\r\n",
    wCS, wDS, wSS, __readeflags(), ReadCR3());
    CreateProcess("Test", "", 0, NULL);
    while (1)
    {
        printf("Concurrency Test.\r\n");
    }
}
\end{minted}

该测试用例将导致操作系统一直创建完全相同的 \lstinline{System} 进程。
每个进程的主线程（入口为 \lstinline{main} 函数），都将使用 \lstinline{printf} 打印信息，打印的信息包括：代码段寄存器、数据段寄存器、栈段寄存器和 \lstinline{EFLAGS} 寄存器，
以及通过系统调用 \lstinline{ReadCR3} 获取到的 \lstinline{CR3} 寄存器。

构建项目后在操作系统中运行上述程序，运行结果如图 \ref{SYSCALL_IN_USER_PROGRAM}。

\begin{figure}[h!]
    \Centering
    \caption{在用户程序中发起系统调用}
    \label{SYSCALL_IN_USER_PROGRAM}
    \includegraphics[scale=0.8]{build/Paper/Assets/Test.png}
\end{figure}


